﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using KZ.Exception;
using KZ.Lottery.BLL;
using KZ.Lottery.Entities;
using KZ.Lottery.Resources;
using KZ.Utilities;

namespace KZ.Lottery
{
    public partial class FrmRuleInsert : Form
    {
        #region Private Variables

        private bool _IsSaved = false;
        private object _PreviousValue;

        #endregion Private Variables

        #region Private Methods

        private void FrmRuleInsert_Load(object sender, EventArgs e)
        {
            LoadChannel();
            if (Action == KZ_Resource.Action_Insert)
            {
                dtgRuleDetail.Rows.Add();
            }
            else if (Action == KZ_Resource.Action_Update || Action == KZ_Resource.Action_Copy)
            {
                LoadRule();
            }
        }

        private void FrmRuleInsert_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_IsSaved)
            {
                FrmRule frm = Application.OpenForms["FrmRule"] as FrmRule;
                if (frm != null)
                {
                    frm.LoadRule();
                }
            }
        }

        private void LoadChannel()
        {
            try
            {
                List<Schedule> scheduleList = ScheduleBLL.GetScheduleListForCMB();

                colMonday.DataSource = scheduleList.Where(s => s.No == DayOfWeek.Monday.ToString() || String.IsNullOrEmpty(s.No)).ToList();
                colTuesday.DataSource = scheduleList.Where(s => s.No == DayOfWeek.Tuesday.ToString() || String.IsNullOrEmpty(s.No)).ToList();
                colWednesday.DataSource = scheduleList.Where(s => s.No == DayOfWeek.Wednesday.ToString() || String.IsNullOrEmpty(s.No)).ToList();
                colThursday.DataSource = scheduleList.Where(s => s.No == DayOfWeek.Thursday.ToString() || String.IsNullOrEmpty(s.No)).ToList();
                colFriday.DataSource = scheduleList.Where(s => s.No == DayOfWeek.Friday.ToString() || String.IsNullOrEmpty(s.No)).ToList();
                colSaturday.DataSource = scheduleList.Where(s => s.No == DayOfWeek.Saturday.ToString() || String.IsNullOrEmpty(s.No)).ToList();
                colSunday.DataSource = scheduleList.Where(s => s.No == DayOfWeek.Sunday.ToString() || String.IsNullOrEmpty(s.No)).ToList();
            }
            catch (DataAccessException ex)
            {
                Global.SetMessage(lblMessage, ex.Message, false);
            }
            catch (System.Exception ex)
            {
                Log.LogEx("LoadChannel", ex);
                Global.SetMessage(lblMessage, KZ_Message.BLM_ERR_GENERAL, false);
            }
        }

        private void LoadRule()
        {
            try
            {
                Rule = RuleBLL.GetRule(RuleID);
            }
            catch (DataAccessException ex)
            {
                Global.SetMessage(lblMessage, ex.Message, false);
            }
            catch (System.Exception ex)
            {
                Log.LogEx("LoadRule", ex);
                Global.SetMessage(lblMessage, KZ_Message.BLM_ERR_GENERAL, false);
            }
        }

        private RuleDetailChannel GetRuleDetailChannel(DataGridViewCell cell)
        {
            return new RuleDetailChannel
            {
                No = dtgRuleDetail.Columns[cell.ColumnIndex].Name.Replace("col", String.Empty),
                ChannelID = Utility.StringParse(cell.Value)
            };
        }

        private void dtgRuleDetail_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            if (e.Control is ComboBox)
            {
                ComboBox cmb = e.Control as ComboBox;
                cmb.DropDownStyle = ComboBoxStyle.DropDown;
                cmb.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                cmb.AutoCompleteSource = AutoCompleteSource.ListItems;
            }
        }

        private void dtgRuleDetail_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            _PreviousValue = dtgRuleDetail[e.ColumnIndex, e.RowIndex].Value;
        }

        private void dtgRuleDetail_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                Global.SetMessage(lblMessage, String.Empty, true);

                string value = Utility.StringParse(dtgRuleDetail[e.ColumnIndex, e.RowIndex].Value);
                if (!String.IsNullOrEmpty(value))
                {
                    foreach (DataGridViewRow row in dtgRuleDetail.Rows)
                    {
                        if (e.RowIndex != row.Index)
                        {
                            if (value == Utility.StringParse(row.Cells[e.ColumnIndex].Value))
                            {
                                dtgRuleDetail[e.ColumnIndex, e.RowIndex].Value = _PreviousValue;
                                throw new BusinessLogicException(KZ_Message.BLM_ERR_CHANNEL_INDAY_EXIST);
                            }
                        }
                    }
                }
            }
            catch (BusinessLogicException ex)
            {
                Global.SetMessage(lblMessage, ex.Message, false);
            }
        }

        private void dtgRuleDetail_KeyPress(object sender, KeyPressEventArgs e)
        {
            switch (e.KeyChar)
            {
                case (char)13:
                case (char)14:
                    if (dtgRuleDetail.RowCount == 0)
                    {
                        dtgRuleDetail.Rows.Add();
                        dtgRuleDetail.CurrentCell = dtgRuleDetail[colMonday.Index, 0];
                        break;
                    }
                    string monday = Utility.StringParse(dtgRuleDetail[colMonday.Index, dtgRuleDetail.RowCount - 1].Value);
                    string tuesday = Utility.StringParse(dtgRuleDetail[colTuesday.Index, dtgRuleDetail.RowCount - 1].Value);
                    string wednesday = Utility.StringParse(dtgRuleDetail[colWednesday.Index, dtgRuleDetail.RowCount - 1].Value);
                    string thursday = Utility.StringParse(dtgRuleDetail[colThursday.Index, dtgRuleDetail.RowCount - 1].Value);
                    string friday = Utility.StringParse(dtgRuleDetail[colFriday.Index, dtgRuleDetail.RowCount - 1].Value);
                    string saturday = Utility.StringParse(dtgRuleDetail[colSaturday.Index, dtgRuleDetail.RowCount - 1].Value);
                    string sunday = Utility.StringParse(dtgRuleDetail[colSunday.Index, dtgRuleDetail.RowCount - 1].Value);

                    if (!String.IsNullOrEmpty(monday) || !String.IsNullOrEmpty(tuesday) ||
                        !String.IsNullOrEmpty(wednesday) || !String.IsNullOrEmpty(thursday) ||
                        !String.IsNullOrEmpty(friday) || !String.IsNullOrEmpty(saturday) ||
                        !String.IsNullOrEmpty(sunday))
                    {
                        dtgRuleDetail.Rows.Add();
                        dtgRuleDetail.CurrentCell = dtgRuleDetail[colMonday.Index, dtgRuleDetail.RowCount - 1];
                    }
                    break;
            }
        }

        private void dtgRuleDetail_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete && dtgRuleDetail.SelectedRows.Count > 0)
            {
                if (DialogResult.Yes == MessageBox.Show(KZ_Message.BLM_CFM_DELETE, String.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {
                    foreach (DataGridViewRow row in dtgRuleDetail.SelectedRows)
                    {
                        dtgRuleDetail.Rows.Remove(row);
                    }
                    if (dtgRuleDetail.RowCount == 0)
                    {
                        dtgRuleDetail.Rows.Add();
                    }
                }
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                dtgRuleDetail.EndEdit();
                Cursor = Cursors.WaitCursor;

                RuleBLL ruleBLL = new RuleBLL();
                if (Action == KZ_Resource.Action_Insert || Action == KZ_Resource.Action_Copy)
                {
                    if (ruleBLL.InsertRule(Rule))
                    {
                        Global.Clear(this);
                        Global.SetMessage(lblMessage, KZ_Message.BLM_SUC_RULE_INSERT, true);
                        txtRuleName.Focus();
                        _IsSaved = true;
                        dtgRuleDetail.Rows.Add();
                    }
                }
                else
                {
                    if (ruleBLL.UpdateRule(Rule))
                    {
                        Global.SetMessage(lblMessage, KZ_Message.BLM_SUC_RULE_UPDATE, true);
                        txtRuleName.Focus();
                        _IsSaved = true;
                    }
                }
            }
            catch (DataAccessException ex)
            {
                Global.SetMessage(lblMessage, ex.Message, false);
            }
            catch (BusinessLogicException ex)
            {
                Global.SetMessage(lblMessage, ex.Message, false);
            }
            catch (System.Exception ex)
            {
                Log.LogEx("btnSave_Click", ex);
                Global.SetMessage(lblMessage, KZ_Message.BLM_ERR_GENERAL, false);
            }
            finally
            {
                Cursor = Cursors.Default;
            }
        }

        #endregion Private Methods

        #region Constructors

        public FrmRuleInsert()
        {
            InitializeComponent();

            colMonday.DisplayMember = ChannelColumns.ChannelName.ToString();
            colMonday.ValueMember = ChannelColumns.ChannelID.ToString();
            colTuesday.DisplayMember = ChannelColumns.ChannelName.ToString();
            colTuesday.ValueMember = ChannelColumns.ChannelID.ToString();
            colWednesday.DisplayMember = ChannelColumns.ChannelName.ToString();
            colWednesday.ValueMember = ChannelColumns.ChannelID.ToString();
            colThursday.DisplayMember = ChannelColumns.ChannelName.ToString();
            colThursday.ValueMember = ChannelColumns.ChannelID.ToString();
            colFriday.DisplayMember = ChannelColumns.ChannelName.ToString();
            colFriday.ValueMember = ChannelColumns.ChannelID.ToString();
            colSaturday.DisplayMember = ChannelColumns.ChannelName.ToString();
            colSaturday.ValueMember = ChannelColumns.ChannelID.ToString();
            colSunday.DisplayMember = ChannelColumns.ChannelName.ToString();
            colSunday.ValueMember = ChannelColumns.ChannelID.ToString();
        }

        #endregion Constructors

        #region Public Members

        public string Action { get; set; }

        public string RuleID { get; set; }

        public Entities.Rule Rule
        {
            get
            {
                return new Entities.Rule
                {
                    RuleID = RuleID,
                    RuleName = txtRuleName.Text,
                    Description = txtDescription.Text,
                    IsActived = chkIsActived.Checked,
                    RuleDetailList = RuleDetailList
                };
            }
            set
            {
                txtRuleName.Text = Action == KZ_Resource.Action_Copy ? String.Empty : value.RuleName;
                txtDescription.Text = value.Description;
                chkIsActived.Checked = value.IsActived;

                RuleDetailList = value.RuleDetailList;
            }
        }

        public List<RuleDetail> RuleDetailList
        {
            get
            {
                List<RuleDetail> ruleDetailList = new List<RuleDetail>();
                int line = 1;
                foreach (DataGridViewRow row in dtgRuleDetail.Rows)
                {
                    List<RuleDetailChannel> ruleDetailChannelList = new List<RuleDetailChannel>();

                    if (!String.IsNullOrEmpty(Utility.StringParse(row.Cells[colMonday.Index].Value))) { ruleDetailChannelList.Add(GetRuleDetailChannel(row.Cells[colMonday.Index])); }
                    if (!String.IsNullOrEmpty(Utility.StringParse(row.Cells[colTuesday.Index].Value))) { ruleDetailChannelList.Add(GetRuleDetailChannel(row.Cells[colTuesday.Index])); }
                    if (!String.IsNullOrEmpty(Utility.StringParse(row.Cells[colWednesday.Index].Value))) { ruleDetailChannelList.Add(GetRuleDetailChannel(row.Cells[colWednesday.Index])); }
                    if (!String.IsNullOrEmpty(Utility.StringParse(row.Cells[colThursday.Index].Value))) { ruleDetailChannelList.Add(GetRuleDetailChannel(row.Cells[colThursday.Index])); }
                    if (!String.IsNullOrEmpty(Utility.StringParse(row.Cells[colFriday.Index].Value))) { ruleDetailChannelList.Add(GetRuleDetailChannel(row.Cells[colFriday.Index])); }
                    if (!String.IsNullOrEmpty(Utility.StringParse(row.Cells[colSaturday.Index].Value))) { ruleDetailChannelList.Add(GetRuleDetailChannel(row.Cells[colSaturday.Index])); }
                    if (!String.IsNullOrEmpty(Utility.StringParse(row.Cells[colSunday.Index].Value))) { ruleDetailChannelList.Add(GetRuleDetailChannel(row.Cells[colSunday.Index])); }

                    if (ruleDetailChannelList.Count > 0)
                    {
                        ruleDetailList.Add(new RuleDetail
                        {
                            RuleDetailID = Utility.StringParse(row.Cells[colRuleDetailID.Index].Value),
                            RuleDetailChannelList = ruleDetailChannelList,
                            Line = line++,
                        });
                    }
                }

                return ruleDetailList;
            }
            set
            {
                if (value.Count > 0)
                {
                    dtgRuleDetail.Rows.Add(value.Count);
                    for (int i = 0; i < value.Count; i++)
                    {
                        dtgRuleDetail[colMonday.Index, i].Value = (value[i].RuleDetailChannelList.SingleOrDefault(rdc => rdc.No == DayOfWeek.Monday.ToString()) ?? new RuleDetailChannel()).ChannelID ?? String.Empty;
                        dtgRuleDetail[colTuesday.Index, i].Value = (value[i].RuleDetailChannelList.SingleOrDefault(rdc => rdc.No == DayOfWeek.Tuesday.ToString()) ?? new RuleDetailChannel()).ChannelID ?? String.Empty;
                        dtgRuleDetail[colWednesday.Index, i].Value = (value[i].RuleDetailChannelList.SingleOrDefault(rdc => rdc.No == DayOfWeek.Wednesday.ToString()) ?? new RuleDetailChannel()).ChannelID ?? String.Empty;
                        dtgRuleDetail[colThursday.Index, i].Value = (value[i].RuleDetailChannelList.SingleOrDefault(rdc => rdc.No == DayOfWeek.Thursday.ToString()) ?? new RuleDetailChannel()).ChannelID ?? String.Empty;
                        dtgRuleDetail[colFriday.Index, i].Value = (value[i].RuleDetailChannelList.SingleOrDefault(rdc => rdc.No == DayOfWeek.Friday.ToString()) ?? new RuleDetailChannel()).ChannelID ?? String.Empty;
                        dtgRuleDetail[colSaturday.Index, i].Value = (value[i].RuleDetailChannelList.SingleOrDefault(rdc => rdc.No == DayOfWeek.Saturday.ToString()) ?? new RuleDetailChannel()).ChannelID ?? String.Empty;
                        dtgRuleDetail[colSunday.Index, i].Value = (value[i].RuleDetailChannelList.SingleOrDefault(rdc => rdc.No == DayOfWeek.Sunday.ToString()) ?? new RuleDetailChannel()).ChannelID ?? String.Empty;
                    }
                }
            }
        }

        #endregion Public Members
    }
}